package org.lee.openoffice.util;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * @author jackielee
 * @version 1.0
 * @description FileUtils
 * @date 2021/5/6
 **/
public class FileUtils {
    private static final String[] PPTEXTS = {"ppt", "pptx", "pptm"};
    private static final String[] IMGEXTS = {"jpg", "jpeg", "png", "bmp"};

    public static String getExt(File file) {
        String fileName = file.getName();
        int index = fileName.lastIndexOf(".");
        return index == -1 ? "" : fileName.substring(index + 1);
    }

    public static String getExt(String fileName) {
        if (StringUtil.isEmpty(fileName)) {
            return "";
        }
        int index = fileName.lastIndexOf(".");
        return index == -1 ? "" : fileName.substring(index + 1);
    }

    public static String getFileName(File file) {
        String fileName = file.getName();
        int index = fileName.lastIndexOf(".");
        return index == -1 ? fileName : fileName.substring(0, index);
    }

    public static boolean checkPpt(File file) {
        String ext = getExt(file);
        return Arrays.stream(PPTEXTS).anyMatch(x -> x.equalsIgnoreCase(ext));
    }

    public static List<File> getFiles(String path) {
        File file = new File(path);
        List<File> files = new ArrayList<>();
        if (!file.exists()) {
            return files;
        }
        if (file.isDirectory()) {
            List<File> list = Arrays.asList(file.listFiles());
            files.addAll(list);
        } else {
            files.add(file);
        }
        return files;
    }

    public static boolean checkImage(File file) {
        String ext = getExt(file);
        return Arrays.stream(IMGEXTS).anyMatch(x -> x.equalsIgnoreCase(ext));
    }

    public static boolean DirExists(String path) {
        File file = new File(path);
        return file.exists() && file.isDirectory();
    }

    public static boolean checkDir(String path) {
        File file = new File(path);
        if (file.exists()) {
            return true;
        }
        return file.mkdirs();
    }

    public static boolean fileExists(String path) {
        File file = new File(path);
        return file.exists() && file.isFile();
    }

    public static String formatPath(String path) {
        return path.toLowerCase().replace("\\", "/");
    }

    public static String getSubPath(String path, String rootPath) {
        return formatPath(path).replace(formatPath(rootPath), "");
    }

    /**
     * byte转字符串
     *
     * @param fileSize
     * @return
     */
    public static String fileSizeString(long fileSize) {
        double gb = 1024.0 * 1024 * 1024;
        double mb = 1024.0 * 1024;
        double kb = 1024.0;
        if (fileSize > gb) {
            double size = fileSize / gb;
            return String.format("%.2fGB", size);
        }
        if (fileSize > mb) {
            double size = fileSize / mb;
            return String.format("%.2fMB", size);
        }
        if (fileSize > kb) {
            double size = fileSize / kb;
            return String.format("%.2fKB", size);
        }
        return String.format("%dB", fileSize);
    }

    public static String readContent(String fileName) {
        if (!fileExists(fileName)) {
            return "";
        }

        try {
            byte[] buffer = Files.readAllBytes(Paths.get(fileName));
            return new String(buffer, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }


    public static List<String> readLines(String fileName) {
        if (!fileExists(fileName)) {
            return new ArrayList<>();
        }

        try {
            return Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    public static void copy(String path, String savePath, ICopying copying, ICopyLog copyLog)
            throws IOException {
        List<File> files = getFiles(path);
        checkDir(savePath);
        if (copying != null && copying.ignore(new File(path))) {
            return;
        }
        for (File file : files) {
            if (copying != null && copying.ignore(file)) {
                continue;
            }
            if (file.isFile()) {
                String target = savePath + File.separator + file.getName();
                file.setReadable(true);
                Files.copy(file.toPath(), Paths.get(target), StandardCopyOption.REPLACE_EXISTING);
                if (copyLog != null) {
                    copyLog.log(String.format("copy the %s to %s", file.getPath(), target));
                }
                continue;
            }
            copy(file.getPath(), savePath + File.separator + file.getName(), copying, copyLog);
        }
    }

    public static void copy(String path, String savePath) throws IOException {
        copy(path, savePath, null, null);
    }

    public interface ICopying {
        boolean ignore(File file);
    }

    public interface ICopyLog {
        void log(String message);
    }

    public static byte[] read(String fileName) {
        if (!fileExists(fileName)) {
            return null;
        }
        File file = new File(fileName);
        try (InputStream is = new FileInputStream(file)) {
            byte[] data = new byte[(int) file.length()];
            is.read(data);
            return data;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static InputStream load(String fileName) {
        if (!fileExists(fileName)) {
            return null;
        }
        File file = new File(fileName);
        try {
            InputStream is = new FileInputStream(file);
            return is;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
